home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld Examples / Tiling Demo / Tiling Demo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-25  |  14.2 KB  |  527 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // Tiling Demo.c
  3. //
  4. // By Vern Jensen, August 1995
  5. ///--------------------------------------------------------------------------------------
  6.  
  7.  
  8. #include <SWIncludes.h>
  9. #include <SWGameUtils.h>
  10. #include <SWDitherDown.h>
  11. #include <SWFPSReport.h>
  12.  
  13. #include "SWApplication.h"
  14. #include "Tiling Demo.h"
  15.  
  16.  
  17. #define    kFullScreenWindow            true        // Makes the window fill the screen
  18. #define    kInterlacedMode                false        // Turns Interlaced mode on/off
  19. #define kSyncToVBL                    false        // Syncs animation to VBL
  20. #define kWorldRectInset                0            // Makes SpriteWorld smaller than window
  21. #define kMaxFPS                        30            // Set to 0 for unrestricted speed
  22.  
  23. #define kNumDiamonds                10            // Number of diamonds
  24. #define kMaxDiamondMoveDelta        5            // Max speed for the diamonds
  25.  
  26. #define kTileWidth                    40            // Don't change these unless you
  27. #define kTileHeight                    40            // change the resource as well.
  28.  
  29.  
  30. enum tileIDs            // Meaningful values for the tileIDs
  31. {
  32.     kWallTile,
  33.     kBoardTile,
  34.     kMaxNumTiles
  35. };
  36.  
  37.  
  38.  
  39. /***********/
  40. /* Globals */
  41. /***********/
  42.  
  43. SpriteWorldPtr        gSpriteWorldP;
  44.  
  45. SpriteLayerPtr        gTopDiamondSpriteLayerP;
  46. SpriteLayerPtr        gBottomDiamondSpriteLayerP;
  47.     
  48. TileMapStructPtr    gTileMapStructP;
  49. SpritePtr            gBallSpriteP;
  50. WindowPtr            gWindowP;
  51.  
  52. DrawProcPtr            gSpriteDrawProc;
  53. short                gNumTileMapRows, gNumTileMapCols;
  54.  
  55.  
  56. ///--------------------------------------------------------------------------------------
  57. // Main
  58. ///--------------------------------------------------------------------------------------
  59.  
  60. void    main( void )
  61. {
  62.     Initialize(kNumberOfMoreMastersCalls);
  63.     
  64.     if (SWHasSystem7())
  65.     {
  66.         SetCursor(*GetCursor(watchCursor));
  67.         
  68.         CreateSpriteWorld();
  69.         SetUpTiling();
  70.         CreateSprites();
  71.         
  72.         SetCursor(&qd.arrow);
  73.         HideCursor();
  74.         
  75.         SetUpAnimation();
  76.         RunAnimation();
  77.         ShutDown();
  78.     }
  79.     else
  80.     {
  81.         CantRunOnThisMachine();
  82.     }
  83. }
  84.  
  85.  
  86. ///--------------------------------------------------------------------------------------
  87. // CreateSpriteWorld
  88. ///--------------------------------------------------------------------------------------
  89.  
  90. void    CreateSpriteWorld( void )
  91. {
  92.     Rect        offscreenRect, worldRect, windRect;
  93.     RgnHandle    mBarUpdateRgn;
  94.     OSErr        err;
  95.     
  96.     gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
  97.     
  98.     if (gWindowP != NULL)
  99.     {
  100.         if (kFullScreenWindow == true)
  101.         {
  102.             SizeWindow(gWindowP, qd.screenBits.bounds.right, 
  103.                     qd.screenBits.bounds.bottom, false);
  104.             MoveWindow(gWindowP, 0, 0, false);
  105.         }
  106.         else
  107.         {
  108.                 // Center window in screen
  109.             windRect = gWindowP->portRect;
  110.             CenterRect(&windRect, &qd.screenBits.bounds);
  111.             MoveWindow(gWindowP, windRect.left, windRect.top, false);
  112.         }
  113.         
  114.         ShowWindow(gWindowP);
  115.         SetPort(gWindowP);
  116.         mBarUpdateRgn = SWHideMenuBar(gWindowP); // Must be done *after* showing window!
  117.         EraseRgn(mBarUpdateRgn);
  118.         
  119.         if (kInterlacedMode)
  120.             PaintRect(&gWindowP->portRect);    // Blacken window for Interlaced mode
  121.     }
  122.     else
  123.         CantFindResource();
  124.     
  125.     
  126.     err = SWEnterSpriteWorld();
  127.     FatalError(err);
  128.  
  129.     
  130.     worldRect = gWindowP->portRect; 
  131.     InsetRect(&worldRect, kWorldRectInset, kWorldRectInset);
  132.     
  133.     
  134.         // Set size of offscreen area
  135.     offscreenRect = worldRect;
  136.     OffsetRect(&offscreenRect, -offscreenRect.left, -offscreenRect.top);
  137.     
  138.  
  139.         // Make offscreen area evenly divisible by tile width & height
  140.     if ( (offscreenRect.right/kTileWidth)*kTileWidth != offscreenRect.right)
  141.         offscreenRect.right = (offscreenRect.right/kTileWidth)*kTileWidth + kTileWidth;
  142.     
  143.     if ( (offscreenRect.bottom/kTileHeight)*kTileHeight != offscreenRect.bottom)
  144.         offscreenRect.bottom = (offscreenRect.bottom/kTileHeight)*kTileHeight + kTileHeight;
  145.     
  146.     
  147.     gNumTileMapRows = offscreenRect.bottom / kTileHeight;
  148.     gNumTileMapCols = offscreenRect.right / kTileWidth;
  149.     
  150.  
  151.     err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP, 
  152.             &worldRect, &offscreenRect, 0);
  153.     FatalError(err);
  154.     
  155.     
  156.     if (gSpriteWorldP->pixelDepth == 8)                        // 256 colors
  157.     {
  158.         gSpriteDrawProc = CompiledSprite8BitDrawProc;
  159.     }
  160.     else if ( !(SW_PPC && gSpriteWorldP->pixelDepth < 8) )    // not 256 colors
  161.     {
  162.         if (kInterlacedMode)
  163.             gSpriteDrawProc = BPAllBitInterlacedMaskDrawProc;
  164.         else
  165.             gSpriteDrawProc = BlitPixieAllBitMaskDrawProc;
  166.     }
  167.     else
  168.     {
  169.         gSpriteDrawProc = SWStdSpriteDrawProc;
  170.     }
  171. }
  172.  
  173.  
  174. ///--------------------------------------------------------------------------------------
  175. // SetUpTiling
  176. ///--------------------------------------------------------------------------------------
  177.  
  178. void    SetUpTiling( void )
  179. {
  180.     short        row, col;
  181.     OSErr        err;
  182.     
  183.     
  184.         // Must be done before we can load the tiles.
  185.     err = SWInitTiling(gSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
  186.     FatalError(err);
  187.     
  188.     err = SWCreateTileMap(&gTileMapStructP, gNumTileMapRows, gNumTileMapCols);
  189.     FatalError(err);
  190.     
  191.     SWInstallTileMap(gSpriteWorldP, gTileMapStructP, 0);
  192.     
  193.     
  194.     // For demonstration purposes, we've decided to load the tiles from CICN
  195.     // resources here, and load them from PICT resources in the Scrolling Demo.
  196.     
  197.         // Load the wall tile
  198.     err = SWLoadTileFromCicnResource(
  199.         gSpriteWorldP, 
  200.         kWallTile,            // tileID
  201.         200,                 // CICN resource ID
  202.         kFatMask);            // maskType
  203.     FatalError(err);
  204.     
  205.         // Load the board ("wire") tile
  206.     err = SWLoadTileFromCicnResource(
  207.         gSpriteWorldP, 
  208.         kBoardTile,            // tileID
  209.         201,                 // CICN resource ID
  210.         kFatMask);            // maskType
  211.     FatalError(err);
  212.  
  213.     
  214.         // Initialize the values in the tileMap
  215.     for (row = 0; row < gNumTileMapRows; row++)
  216.     {
  217.         for (col = 0; col < gNumTileMapCols; col++)
  218.         {
  219.             if (row == 0 || col == 0 || row == gNumTileMapRows-1 || col == gNumTileMapCols-1)
  220.                 gTileMapStructP->tileMap[row][col] = kWallTile;
  221.             else
  222.                 gTileMapStructP->tileMap[row][col] = kBoardTile;
  223.         }
  224.     }
  225. }
  226.  
  227.  
  228. ///--------------------------------------------------------------------------------------
  229. // CreateSprites
  230. ///--------------------------------------------------------------------------------------
  231.  
  232. void    CreateSprites( void )
  233. {
  234.     SpritePtr            diamondSpriteP;
  235.     SpritePtr            tempSpriteP;
  236.     short                spriteNum;
  237.     Point                moveDelta, mousePoint;
  238.     Rect                moveBounds;
  239.     OSErr                err;
  240.     
  241.     
  242.         // Create the sprite layers
  243.     SWCreateSpriteLayer(&gTopDiamondSpriteLayerP);
  244.     SWCreateSpriteLayer(&gBottomDiamondSpriteLayerP);
  245.     FatalError(SWStickyError());
  246.     
  247.     
  248.     moveBounds = gSpriteWorldP->backRect;
  249.     InsetRect(&moveBounds, 40, 40);
  250.     
  251.         // create and set up the diamond sprites
  252.     for (spriteNum = 0; spriteNum < kNumDiamonds; spriteNum++)
  253.     {
  254.         if (spriteNum == 0)
  255.         {
  256.             err = SWCreateSpriteFromPictResource(gSpriteWorldP,
  257.                 &diamondSpriteP, 
  258.                 NULL,        // pointer to memory for sprite
  259.                 128,         // picture resource id
  260.                 128,         // mask resource id (we use self-masking)
  261.                 1,             // max frames
  262.                 kFatMask);    // mask type
  263.             FatalError(err);
  264.  
  265.             tempSpriteP = diamondSpriteP;
  266.             
  267.             if (gSpriteWorldP->pixelDepth == 8)
  268.                 SWCompileSprite(diamondSpriteP);
  269.         }
  270.         else
  271.         {
  272.             err = SWCloneSprite(diamondSpriteP, &tempSpriteP, NULL);
  273.             FatalError(err);
  274.         }
  275.         
  276.  
  277.         SWSetSpriteMoveBounds(tempSpriteP, &moveBounds);
  278.         SWSetSpriteMoveProc(tempSpriteP, DiamondSpriteMoveProc);
  279.         
  280.         SWSetSpriteLocation(tempSpriteP, 
  281.                 GetRandom(40, gSpriteWorldP->backRect.right-80), 
  282.                 GetRandom(40, gSpriteWorldP->backRect.bottom-80));
  283.         
  284.         do
  285.         {
  286.             moveDelta.h = GetRandom(-kMaxDiamondMoveDelta, kMaxDiamondMoveDelta);
  287.             moveDelta.v = GetRandom(-kMaxDiamondMoveDelta, kMaxDiamondMoveDelta);
  288.         } while (!moveDelta.v || !moveDelta.h);
  289.         
  290.         SWSetSpriteMoveDelta(tempSpriteP, moveDelta.h, moveDelta.v);
  291.         SWSetSpriteDrawProc(tempSpriteP, gSpriteDrawProc);
  292.         err = SWAddSprite(gTopDiamondSpriteLayerP, tempSpriteP);
  293.         FatalError(err);
  294.     }
  295.     
  296.     
  297.         // Create the ball sprite
  298.     err = SWCreateSpriteFromCicnResource(gSpriteWorldP, &gBallSpriteP, NULL, 
  299.             128, 1, kFatMask);    
  300.     FatalError(err);
  301.     
  302.     if (gSpriteWorldP->pixelDepth == 8)
  303.         SWCompileSprite(gBallSpriteP);
  304.     
  305.     
  306.         // Set up the ball sprite
  307.     err = SWAddSprite(gTopDiamondSpriteLayerP, gBallSpriteP);
  308.     FatalError(err);
  309.     SWSetSpriteMoveProc(gBallSpriteP, BallSpriteMoveProc);
  310.     SWSetSpriteDrawProc(gBallSpriteP, gSpriteDrawProc);
  311.     SWSetFrameHotSpot(gBallSpriteP->curFrameP, 20, 20);
  312.     GetMouse(&mousePoint);
  313.     SWSetSpriteLocation(gBallSpriteP, mousePoint.h, mousePoint.v);
  314.     
  315.     SWAddSpriteLayer(gSpriteWorldP, gBottomDiamondSpriteLayerP);    // Add bottom first, so it is drawn first
  316.     SWAddSpriteLayer(gSpriteWorldP, gTopDiamondSpriteLayerP);        // Add top last, so it is drawn last
  317.  
  318.     SWLockSpriteWorld(gSpriteWorldP);
  319.     
  320.     
  321.         // Test out the dithering routines in DitherDown.c. 
  322.         // See DitherDown.c for more info.
  323.     if (gSpriteWorldP->pixelDepth < 8)
  324.     {
  325.             // Dither the diamond sprite
  326.         DitherDownPict(128, diamondSpriteP->frameArray[0]->framePort);
  327.         LowerMaskDepth(128, diamondSpriteP->frameArray[0]->maskPort);
  328.         
  329.             // Dither the wall tile
  330.         DitherDownCicn(200, gSpriteWorldP->tileFrameArray[kWallTile]->framePort);
  331.     }
  332. }
  333.  
  334.  
  335. ///--------------------------------------------------------------------------------------
  336. // SetUpAnimation
  337. ///--------------------------------------------------------------------------------------
  338.  
  339. void    SetUpAnimation( void )
  340. {
  341.     SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
  342.     SWSyncSpriteWorldToVBL(gSpriteWorldP, kSyncToVBL);
  343.     SWSetCleanUpSpriteWorld(gSpriteWorldP);
  344.     
  345.     SWSetSpriteLayerUnderTileLayer(gBottomDiamondSpriteLayerP, 0);
  346.     
  347.  
  348.     if (gSpriteWorldP->pixelDepth == 8)        // 256 colors
  349.     {
  350.         if (kInterlacedMode)
  351.         {
  352.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
  353.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
  354.             SWSetPartialMaskDrawProc(gSpriteWorldP, BP8BitInterlacedPartialMaskDrawProc);
  355.         }
  356.         else
  357.         {
  358.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
  359.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
  360.             SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixie8BitPartialMaskDrawProc);
  361.         }
  362.     }
  363.     else if ( !(SW_PPC && gSpriteWorldP->pixelDepth < 8) )    // not 256 colors
  364.     {
  365.         if (kInterlacedMode)
  366.         {
  367.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
  368.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
  369.             SWSetPartialMaskDrawProc(gSpriteWorldP, BPAllBitInterlacedPartialMaskDrawProc);
  370.         }
  371.         else
  372.         {
  373.             SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  374.             SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  375.             SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixieAllBitPartialMaskDrawProc);
  376.         }
  377.     }
  378.     
  379.     
  380.         // Make sure CopyBits, if used, doesn't try to colorize things
  381.     SWSetPortToWindow(gSpriteWorldP);
  382.     ForeColor(blackColor);
  383.     BackColor(whiteColor);
  384.     
  385.  
  386.     SWDrawTilesInBackground(gSpriteWorldP);
  387.     SWUpdateSpriteWorld(gSpriteWorldP, true);
  388. }
  389.  
  390.  
  391. ///--------------------------------------------------------------------------------------
  392. //  RunAnimation
  393. ///--------------------------------------------------------------------------------------
  394.  
  395.     
  396. void    RunAnimation( void )
  397. {
  398.     unsigned long        frames;
  399.     
  400.     frames = 0;
  401.     StartTimer();
  402.     
  403.     FatalError( SWStickyError() ); // Make sure no errors got past us during setup
  404.     
  405.     while (!Button())
  406.     {
  407.         SWProcessSpriteWorld(gSpriteWorldP);
  408.         FatalError( SWStickyError() );    // Make sure no errors occurred during a MoveProc, etc.
  409.         SWAnimateSpriteWorld(gSpriteWorldP);
  410.         
  411.         if (gSpriteWorldP->frameHasOccurred)
  412.             frames++;
  413.     }
  414.     
  415.     SWShowMenuBar(gWindowP);
  416.     ShowResults(frames);
  417. }
  418.  
  419.  
  420. ///--------------------------------------------------------------------------------------
  421. //  ShutDown (clean up and dispose of the SpriteWorld)
  422. ///--------------------------------------------------------------------------------------
  423.  
  424.  
  425. void    ShutDown( void )
  426. {
  427.     SWUnlockSpriteWorld(gSpriteWorldP);
  428.     SWDisposeSpriteWorld(&gSpriteWorldP);
  429.     SWExitSpriteWorld();
  430.     
  431.     FlushEvents(everyEvent, 0);
  432.     ShowCursor();
  433. }
  434.  
  435.  
  436. ///--------------------------------------------------------------------------------------
  437. //  BallSpriteMoveProc - makes the ball follow the mouse
  438. ///--------------------------------------------------------------------------------------
  439.  
  440. SW_FUNC void BallSpriteMoveProc(SpritePtr srcSpriteP)
  441. {
  442.     Point                mousePoint;
  443.     SpritePtr            tempSpriteP;
  444.     EventRecord            event;
  445.     short                theChar;
  446.     
  447.     
  448.         // Move the ball sprite
  449.     GetMouse(&mousePoint);
  450.     
  451.         // Subtract any offset from worldRect to window if a worldRect is used
  452.     mousePoint.h -= gSpriteWorldP->windRect.left;
  453.     mousePoint.v -= gSpriteWorldP->windRect.top;
  454.     
  455.         // This sprite uses a hotSpot of 20,20, so all we have to do is move its
  456.         // hotPoint to the current mouse location, and it will appear centered properly
  457.     SWMoveSprite(srcSpriteP, mousePoint.h, mousePoint.v);
  458.     
  459.     
  460.         // Change ball sprite layers if the spacebar was hit
  461.     while ( GetOSEvent(keyDownMask, &event) )
  462.     {
  463.         theChar = (event.message & charCodeMask);
  464.         
  465.         if (theChar == ' ')
  466.         {
  467.             if (srcSpriteP->parentSpriteLayerP == gBottomDiamondSpriteLayerP)
  468.             {
  469.                 SWRemoveSprite(srcSpriteP);
  470.                 SWAddSprite(gTopDiamondSpriteLayerP, srcSpriteP);
  471.             }
  472.             else
  473.             {
  474.                 SWRemoveSprite(srcSpriteP);
  475.                 SWAddSprite(gBottomDiamondSpriteLayerP, srcSpriteP);
  476.             }
  477.         }
  478.     }
  479.     
  480.         
  481.         // Check for collision with diamonds in same layer as ball //
  482.  
  483.     tempSpriteP = srcSpriteP->parentSpriteLayerP->headSpriteP;
  484.  
  485.     while (tempSpriteP != NULL)
  486.     {
  487.             // are the sprite’s rectangles overlapping?
  488.         if (tempSpriteP != gBallSpriteP &&
  489.             (tempSpriteP->destFrameRect.top < gBallSpriteP->destFrameRect.bottom) &&
  490.             (tempSpriteP->destFrameRect.bottom > gBallSpriteP->destFrameRect.top) &&
  491.             (tempSpriteP->destFrameRect.left < gBallSpriteP->destFrameRect.right) &&
  492.             (tempSpriteP->destFrameRect.right > gBallSpriteP->destFrameRect.left))
  493.         {
  494.                 // Check to see if the masks overlap
  495.             if ( SWRegionCollision(tempSpriteP, gBallSpriteP)) 
  496.             {
  497.                     // Switch diamond position above/under tiles
  498.                 if (tempSpriteP->parentSpriteLayerP == gBottomDiamondSpriteLayerP)
  499.                 {
  500.                     SWRemoveSprite(tempSpriteP);
  501.                     SWAddSprite(gTopDiamondSpriteLayerP, tempSpriteP);
  502.                 }
  503.                 else
  504.                 {
  505.                     SWRemoveSprite(tempSpriteP);
  506.                     SWAddSprite(gBottomDiamondSpriteLayerP, tempSpriteP);
  507.                 }
  508.             }
  509.         }
  510.         
  511.         tempSpriteP = tempSpriteP->nextSpriteP;
  512.     }
  513. }
  514.  
  515.  
  516. ///--------------------------------------------------------------------------------------
  517. //  DiamondSpriteMoveProc
  518. ///--------------------------------------------------------------------------------------
  519.  
  520.  
  521. SW_FUNC void DiamondSpriteMoveProc(SpritePtr ballSpriteP)
  522. {    
  523.     SWOffsetSprite(ballSpriteP, ballSpriteP->horizMoveDelta, ballSpriteP->vertMoveDelta);
  524.     (void)SWBounceSprite(ballSpriteP);
  525. }
  526.  
  527.